package com.googlecode.garbagecan.cxfstudy.filetransfer;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.common.gzip.GZIPInInterceptor;
import org.apache.cxf.transport.common.gzip.GZIPOutInterceptor;

public class FileTransferClient {
	
	private static final String address = "http://localhost:9000/ws/jaxws/fileTransferService";
	
	private static final String clientFile = "/home/fkong/temp/client/test.zip";
	private static final String serverFile = "/home/fkong/temp/server/test.zip";
	
	public static void main(String[] args) throws Exception {
		long start = System.currentTimeMillis();
//		list();
//		uploadFile();
//		downloadFile();
		long stop = System.currentTimeMillis();
		System.out.println("Time: " + (stop - start));
	}

	private static void list() throws FileTransferException {
		JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
		factoryBean.setAddress(address);
		factoryBean.setServiceClass(FileTransferService.class);
		Object obj = factoryBean.create();

		Client client = ClientProxy.getClient(obj);
		Endpoint endpoint = client.getEndpoint();
		endpoint.getInInterceptors().add(new LoggingInInterceptor());
		endpoint.getOutInterceptors().add(new LoggingOutInterceptor());
		endpoint.getInInterceptors().add(new GZIPInInterceptor());
		endpoint.getOutInterceptors().add(new GZIPOutInterceptor());
		
		FileTransferService service = (FileTransferService) obj;
		MyFile[] myFiles = service.list("/home/fkong/share");
		for (MyFile myFile : myFiles) {
			System.out.println("----------------------------------------");
			System.out.println(myFile.getPath());
			System.out.println(myFile.getName());
			System.out.println(myFile.isFile());
			System.out.println(myFile.isDirectory());
		}
	}
	
	private static void uploadFile() throws FileTransferException {
		InputStream is = null;
		try {
			FileTransferObject fto = new FileTransferObject();
			is = new FileInputStream(clientFile);
			byte[] bytes = new byte[1024 * 1024];
			while (true) {
				int size = is.read(bytes);
				if (size <= 0) {
					break;
				}
				
				byte[] fixedBytes = Arrays.copyOfRange(bytes, 0, size);
				fto.setClientFile(clientFile);
				fto.setServerFile(serverFile);
				fto.setBytes(fixedBytes);
				
				uploadFile(fto);
				
				fto.setPosition(fto.getPosition() + fixedBytes.length);
			}
		} catch(IOException e) {
			throw new FileTransferException(e.getMessage(), e);
		} finally {
			IOUtils.closeQuietly(is);
		}
	}
	
	private static void uploadFile(FileTransferObject myFile) throws FileTransferException {
		JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
		factoryBean.setAddress(address);
		factoryBean.setServiceClass(FileTransferService.class);
		Object obj = factoryBean.create();

		Client client = ClientProxy.getClient(obj);
		Endpoint endpoint = client.getEndpoint();
		endpoint.getInInterceptors().add(new LoggingInInterceptor());
		endpoint.getOutInterceptors().add(new LoggingOutInterceptor());
		endpoint.getInInterceptors().add(new GZIPInInterceptor());
		endpoint.getOutInterceptors().add(new GZIPOutInterceptor());
		
		FileTransferService service = (FileTransferService) obj;
		service.uploadFile(myFile);
	}
	
	private static void downloadFile() throws FileTransferException {
		FileTransferObject fto = new FileTransferObject();
		fto.setServerFile(serverFile);
		long position = 0;
		while (true) {
			fto.setPosition(position);
			fto = downloadFile(fto);
			if (fto.getBytes().length <= 0) {
				break;
			}
			
			OutputStream os = null;
			try {
				if (position != 0) {
					os = FileUtils.openOutputStream(new File(clientFile), true);
				} else {
					os = FileUtils.openOutputStream(new File(clientFile), false);
				}
				os.write(fto.getBytes());
			} catch(IOException e) {
				throw new FileTransferException(e.getMessage(), e);
			} finally {
				IOUtils.closeQuietly(os);
			}
			
			position += fto.getBytes().length;
		}
	}
	
	private static FileTransferObject downloadFile(FileTransferObject myFile) throws FileTransferException {
		JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
		factoryBean.setAddress(address);
		factoryBean.setServiceClass(FileTransferService.class);
		Object obj = factoryBean.create();

		Client client = ClientProxy.getClient(obj);
		Endpoint endpoint = client.getEndpoint();
		endpoint.getInInterceptors().add(new LoggingInInterceptor());
		endpoint.getOutInterceptors().add(new LoggingOutInterceptor());
		endpoint.getInInterceptors().add(new GZIPInInterceptor());
		endpoint.getOutInterceptors().add(new GZIPOutInterceptor());
		
		FileTransferService service = (FileTransferService) obj;
		return service.downloadFile(myFile);
	}
}
